package springsecurity.authentication;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import springsecurity.utlis.AuthCache;
import springsecurity.dao.AuthConfigAttribute;
import springsecurity.dao.enums.AuthorityConstants;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;

/**
 * Created with IntelliJ IDEA.
 *
 * @User: c.c
 * @Date: 2022/6/14
 * @Time: 14:38
 * @Description: 用户权限匹配
 *
 * Security需要用到一个实现了AccessDecisionManager接口的类
 * 类功能：根据当前用户的信息，和目标url涉及到的权限，判断用户是否可以访问
 * 判断规则：用户只要匹配到目标url权限中的一个role就可以访问
 */

public class CustomAccessDecisionManager implements AccessDecisionManager {


    @Override
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
        HttpServletRequest req = ((FilterInvocation) o).getRequest();
        //验证豁免
        if (collection == null || collection.isEmpty()) {
            return;
        }

        //获得权限数据  因为我的collection Collections.singletonList使用的是这个方法，所以只存在一个
        final AuthConfigAttribute configAttribute = (AuthConfigAttribute) collection.stream().findFirst().get();
        String attribute = configAttribute.getAttribute();
        String authId = configAttribute.getAuthId();

        //不需要验证权限的
        if (AuthorityConstants.PERMIT_ALL.equals(attribute)) {
            return;
        }

        //获取缓存数据
        final String authName = AuthCache.getInstance().getAuthName(authId);

        //登录验证
//        if (authentication instanceof AnonymousAuthenticationToken || !authentication.isAuthenticated()) {
//            throw new InsufficientAuthenticationException(String.format("[%s]接口验证未登录", authName));
//        }

        //角色判断
        for (GrantedAuthority authority : authentication.getAuthorities()){
            final String temp = authority.getAuthority();
            if (temp.startsWith("ROLE_")){
                final String roleCode = temp.substring(AuthorityConstants.ROLE_PREFIX.length());
                if (roleCode.equals("admin")){
                    return;
                }
                System.out.println("-----------------该页面你没权限登录---------------");
                throw new AccessDeniedException(String.format("该页面你没权限登录", authName));
            }
        }
        throw new AccessDeniedException(String.format("用户缺少[%s]权限", authName));
    }

    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return false;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return false;
    }
}
